package main

import (
	"BilibiliConvertGo/util"
	"bufio"
	"bytes"
	"fmt"
	"github.com/google/uuid"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
	"time"
)

// 检测ffmpeg环境是否存在
func checkFFmpeg() bool {
	cmd := exec.Command("cmd", "/c", "start", "/b", "ffmpeg", "-version")
	cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
	pipe, err := cmd.StdoutPipe()
	if err != nil {
		return false
	}
	if err := cmd.Start(); err != nil {
		return false
	}
	reader := bufio.NewReader(pipe)
	for true {
		line, _, err := reader.ReadLine()
		if err != nil {
			fmt.Printf("err: %v", err)
			return false
		}
		if strings.Index(string(line[:]), "version") != -1 {
			return true
		}
	}
	return false
}

func mergeM4S(videoPath string, audioPath string, outputPath string, overrideFlag bool, onlyAudio bool, bitrate int64, progressCallBack func(p float32)) {
	modifyBitrate := false
	finalBitrate := -1
	if bitrate != 100 {
		videoBitrate := parseBitrateInfo(videoPath)
		if videoBitrate != -1 {
			finalBitrate = int(float64(videoBitrate) * 0.01 * float64(bitrate))
			modifyBitrate = true
		}
	}
	// 创建文件夹
	_ = os.Mkdir(".bilibili_convert_temp", os.ModePerm)
	progressPath := ".bilibili_convert_temp" + string(filepath.Separator) + uuid.New().String()

	// 是否覆盖输出文件
	overrideOutput := "-n"
	if overrideFlag {
		overrideOutput = "-y"
	}

	// 执行转换命令
	cmd := exec.Command("cmd", "/c")
	if onlyAudio {
		cmd = exec.Command(
			"cmd",
			"/c",
			"start",
			"/b",
			"ffmpeg",
			"-i",
			audioPath,
			"-progress",
			progressPath,
			outputPath,
			overrideOutput)
	} else {
		if modifyBitrate && finalBitrate != -1 {
			cmd = exec.Command(
				"cmd",
				"/c",
				"start",
				"/b",
				"ffmpeg",
				"-i",
				videoPath,
				"-i",
				audioPath,
				"-b:v",
				strconv.FormatInt(int64(finalBitrate), 10)+"k",
				"-progress",
				progressPath,
				outputPath,
				overrideOutput)
		} else {
			cmd = exec.Command(
				"cmd",
				"/c",
				"start",
				"/b",
				"ffmpeg",
				"-i",
				videoPath,
				"-i",
				audioPath,
				"-progress",
				progressPath,
				"-codec",
				"copy",
				outputPath,
				overrideOutput)
		}
	}
	cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr

	// 开启线程，检测文件转换进度
	go func() {
		time.Sleep(time.Duration(500) * time.Millisecond)
		// 计算文件转换完成之后的文件大小
		size2 := util.GetFileSize(audioPath)
		totalSize := float32(size2)
		if !onlyAudio {
			size1 := util.GetFileSize(videoPath)
			totalSize = float32(size1) + float32(size2)
		}
		file, err := os.Open(progressPath)
		if err != nil {
			return
		}
		defer file.Close()
		reader := bufio.NewReader(file)
		for {
			line, _, err := reader.ReadLine()
			if err == io.EOF {
				continue
			}
			// 获取已转换的文件大小
			if strings.Index(string(line), "total_size=") != -1 {
				// 计算转换的进度
				f1, _ := strconv.ParseInt(string(line[11:]), 10, 64)
				pro := float32(f1) / totalSize * 100
				if pro >= 100 {
					pro = 99.99
				}
				progressCallBack(pro)
			}
			// 判断是否转换完成
			if strings.Index(string(line), "progress=end") != -1 {
				progressCallBack(100)
				return
			}
		}
	}()
	err := cmd.Run()
	if err != nil {
		return
	}
}

func parseBitrateInfo(filepath string) int64 {
	cmd := exec.Command("ffmpeg", "-i", filepath)
	infoOutput, _ := cmd.CombinedOutput()

	output := string(infoOutput)

	// 示例：假设输出中含有 "bitrate: 2000 kb/s" 的信息
	// 使用字符串处理方法截取 "bitrate: " 后面的部分
	startIndex := strings.Index(output, "bitrate: ")
	if startIndex == -1 {
		return -1
	}
	startIndex += len("bitrate: ")

	// 使用字符串处理方法截取 " kb/s" 前面的部分
	endIndex := strings.Index(output[startIndex:], " kb/s")
	if endIndex == -1 {
		return -1
	}
	parseInt, err := strconv.ParseInt(output[startIndex:startIndex+endIndex], 10, 64)
	if err != nil {
		return -1
	}
	return parseInt
}
